#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
通过歌单得id进行  爬取
"""

import requests, os, csv, ssl, time, random  # ssl全局关闭认证
from bs4 import BeautifulSoup


class SpiderWYMusicApp():  # 应用

    def __init__(self):  # 初始化方法
        # 根据输入的歌单id进行爬取
        self.id = input('请输入歌单ID：')  # 2862539190
        # url用来拼接歌单id进行请求页面
        self.url = 'https://music.163.com/playlist'
        # download url用来拼接歌曲id进行下载歌曲
        self.download_url = 'https://music.163.com/song/media/outer/url'
        # 设置请求头，用来模拟请求环境
        self.head = {  # 定制头部
            # 'Referer':'https://music.163.com/',
            # 'Host':'music.163.com',
            # 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
        }
        # 设置代理，用来屏蔽封ip风险
        self.proxies = {  # 代理IP
            # 'http://':'60.13.42.14:9999',
            # 'https://':'58.220.95.116:10122'
        }
        # 保存音乐信息
        self.music_dict = {}

    def sendReqPlayList(self):  # 1 访问网易云歌单列表页面
        # 发起请求，提交参数
        resp = requests.get(url=self.url, params={'id': self.id}, headers=self.head, proxies=self.proxies)
        # 验证路径、状态码
        print(resp.url, resp.status_code)
        # 解析数据源
        soup = BeautifulSoup(resp.text, 'html.parser')

        # 获取网页标题，作为csv文件名称使用
        self.title = soup.title.string

        # 根据抓包分析，获取隐藏的数据标签 ul
        ul = soup.find(name='ul', attrs={'class': 'f-hide'})
        # 获取ul内部的a标签
        a_list = ul.find_all(name='a')
        # 循环：获取音乐信息
        for a in a_list:
            # 提取a标签中的文本内容
            music_name = a.string.strip()
            # 提取a标签中的链接
            music_id = a.attrs.get('href')
            # 保存到字典
            self.music_dict[music_name] = music_id
            # print(music_name,music_id)

    def save(self):  # 2 保存本地
        """ 此方法用来保存内容 """
        # 定义一个路径
        dir_path = os.path.abspath('.') + '/music/'
        # 验证路径是否存在
        if not os.path.exists(dir_path):
            # 如果不存在则创建
            os.mkdir(dir_path)

        # 打开一个csv文件
        file = open(dir_path + self.title + '.csv', mode='w', encoding='utf-8', newline='')
        # 调取写入方法
        csvfile = csv.writer(file)
        # 设定标题内容
        csvfile.writerow(['音乐名称', '音乐路径'])

        # 音乐访问出现404，VIP音乐
        for key, value in self.music_dict.items():
            # 只获取/song?id=489998494中的id，所以前五位字符不需要
            value = self.download_url + value[5:]
            csvfile.writerow([key, value])
        # 刷新文件
        file.flush()
        # 关闭文件，避免溢出问莪媞
        file.close()

        # 问题：音乐文件下载，内容缺失，播放不了
        for key, value in self.music_dict.items():
            # File文件url地址，可以下载
            # try是避免报错之类的问题，导致直接报错，捕获错误并输出
            try:
                # 拼接下载链接
                value = self.download_url + value[5:]

                # 请求获取音乐文件的二进制
                resp = requests.get(url=value, headers=self.head, proxies=self.proxies)

                # r 读取 rb 读取字节 w 写入 wb写入字节
                music_file = open(dir_path + key + '.mp3', "wb")
                music_file.write(resp.content)
                print(key, '下载成功')

                # for速度很快的，需要睡眠,随机时间 1~3 秒
                time.sleep(random.random() * 2 + 1)

            except Exception as e:
                print(e)
                print(key, '下载失败')

    def run(self):  # 入口
        # 发起请求
        self.sendReqPlayList()
        self.save()


# 创建实例对象
app = SpiderWYMusicApp()
# 调用实例方法
app.run()